package labox.innovation.gameserver.taskmanager;

import java.io.File;
import java.io.FileInputStream;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javolution.util.FastList;
import labox.innovation.config.Config;
import labox.innovation.gameserver.timer.Timer;
import labox.innovation.gameserver.util.Broadcast;

/**
 * 自动发送的公告管理器
 * 
 * @author nBd
 */
public final class AutoAnnounceTaskManager {

	protected static final Logger _log = LoggerFactory.getLogger(AutoAnnounceTaskManager.class.getName());

	protected List<AutoAnnouncement> _announces = new FastList<AutoAnnouncement>();

	public static AutoAnnounceTaskManager getInstance() {
		return SingletonHolder._instance;
	}

	private AutoAnnounceTaskManager() {
		restore();
	}

	public void restore() {
		if (!_announces.isEmpty()) {
			for (AutoAnnouncement a : _announces)
				a.stopAnnounce();

			_announces.clear();
		}

		FileInputStream fin = null;
		try {
			File file = new File(Config.DATAPACK_ROOT, "data/autoannouncements.xml");
			if (file.exists()) {
				fin = new FileInputStream(file);
				DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
				DocumentBuilder builder = factory.newDocumentBuilder();
				Document document = builder.parse(fin);
				Element root;
				root = document.getDocumentElement();
				if (root.getTagName().compareTo("AutoAnnouncements") != 0) {
					throw new Exception("Not a AutoAnnouncement file!");
				}
				NodeList nl = root.getElementsByTagName("AutoAnnouncement");

				for (int i = -1; ++i < nl.getLength();) {
					Element e = (Element) nl.item(i);
					int initial = Integer.parseInt(e.getAttribute("initial"));
					int delay = Integer.parseInt(e.getAttribute("delay"));
					int repeat = Integer.parseInt(e.getAttribute("cycle"));
					String memo = e.getTextContent();
					AutoAnnouncement ann = new AutoAnnouncement(delay, repeat, memo);
					ann.setTimer(new Timer(initial, true, ann));
					if (!_announces.contains(ann))
						_announces.add(ann);
				}
			} else {
				_log.info("data/autoannouncements.xml doesn't exist", Config.SERVER_ID);
			}

		} catch (Exception e) {
			_log.error("AutoAnnoucements: Failed to load announcements data.", Config.SERVER_ID, e);
		} finally {
			try {
				if (fin != null)
					fin.close();
			} catch (Exception e) {
			}
		}
		_log.info("AutoAnnoucements: Loaded " + _announces.size() + "  Auto Annoucement Data.", Config.SERVER_ID);
	}

	private class AutoAnnouncement implements Runnable {
		private int _delay;

		private int _repeat = -1;

		private String _memo;

		private Timer _t;

		public AutoAnnouncement(int delay, int repeat, String memo) {
			_delay = delay;
			_repeat = repeat;
			_memo = memo;
		}

		public void setTimer(Timer t) {
			_t = t;
			t.start();
		}

		public void stopAnnounce() {
			_t.cancel();
			_t = null;
		}

		public void run() {
			announce(_memo);
			if (_t == null)
				return;
			_repeat--;
			if (_repeat < 0) {
				_t.cancel();
			}
			_t.setDelay(_delay);
		}
	}

	public void announce(String text) {
		Broadcast.announceToOnlinePlayers(text);
	}

	@SuppressWarnings("synthetic-access")
	private static class SingletonHolder {
		protected static final AutoAnnounceTaskManager _instance = new AutoAnnounceTaskManager();
	}
}